;; Tests of the non-robust linear algebra functions
;; Copyright (C) 2025  Rocks Mazama
;;
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <https://www.gnu.org/licenses/>.

(ns mazama.linalg.determinant-test
  (:require
   [clojure.test :refer [deftest is testing]]
   [mazama.linalg.determinant :as determinant]))

(deftest determinant-0
  (testing "https://math.stackexchange.com/questions/1848952/finding-the-determinant-of-the-5x5-matrix-but-cant-put-it-in-lower-triangular-f"
    (let [m {:ncols 5 :data [ 3  0  0  3  0
                             -3  0 -2  0  0
                              0 -1  0  0 -3
                              0  0  0  3  3
                              0 -1  2  0  0]}
          expected 0]
      (is (== expected (determinant/determinant m))))))

(deftest determinant-1
  (testing "http://vergil.chemistry.gatech.edu/notes/linear_algebra/node3.html"
    (let [m {:ncols 1 :data [-37]}
          expected -37]
      (is (== expected (determinant/determinant m))))))

(deftest determinant-2
  (testing "https://www.mathcentre.ac.uk/resources/uploaded/sigma-matrices4-2009-1.pdf"
    (let [m {:ncols 2 :data [4 3 5 -1]}
          expected -19]
      (is (== expected (determinant/determinant m)))
      (is (== expected (apply determinant/determinant-2 (:data m)))))))

(deftest determinant-3
  (testing "http://www.math.uwaterloo.ca/~jmckinno/Math106/Week10/Lecture4f.pdf"
    (let [m {:ncols 3 :data [3 7 -9 6 1 4 -9 5 2]}
          expected -741]
      (is (== expected (determinant/determinant m)))
      (is (== expected (apply determinant/determinant-3 (:data m)))))))

(deftest determinant-4
  (testing "http://www.math.uwaterloo.ca/~jmckinno/Math106/Week10/Lecture4f.pdf"
    (let [m {:ncols 4 :data [0 5 -2 -4 2 4 -2 8 -3 4 -1 1 5 5 -8 9]}
          expected -1050]
      (is (== expected (determinant/determinant m)))
      (is (== expected (apply determinant/determinant-4 (:data m)))))))

(deftest determinant-5
  (testing "http://www.math.uwaterloo.ca/~jmckinno/Math106/Week10/Lecture4f.pdf"
    (let [m {:ncols 5 :data [ 1   2  0 -1  2
                              2   1  1  0  7
                              0   3  0  0 -2
                             -1 -10  1  1  1
                              0   9  0  0  1]}
          expected 42]
      (is (== expected (determinant/determinant m)))))
  (testing "https://matrix.reshish.com/determinant.php"
    (let [m {:ncols 5 :data [ 1 2 3 4 5
                             -2 3 4 5 -6
                             3 4 5 -6 -7
                             4 3 2 1 4
                             -3 -2 -4 -2 -4]}
          expected -1632]
      (is (== expected (determinant/determinant m)))))
  (testing "zero"
    (let [m {:ncols 5 :data [0 0 0 0 1
                             0 0 0 1 0
                             0 0 1 0 0
                             0 0 0 1 0
                             1 0 0 0 0]}]
      (is (zero? (determinant/determinant m))))))
